package com.salt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.salt.config.AppConfig;
import com.salt.entity.User;
import com.salt.mapper.UserMapper;
import com.salt.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.regex.Pattern;
import java.time.LocalDate;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final AppConfig appConfig;
    
    // 手机号正则表达式
    private static final String MOBILE_PATTERN = "^1[3-9]\\d{9}$";
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public User register(String mobile, String password, String inviteCode, String nickName) {
        // 验证手机号格式
        if (!isValidMobile(mobile)) {
            throw new IllegalArgumentException("手机号格式不正确");
        }
        
        // 检查手机号是否已注册
        if (isMobileRegistered(mobile)) {
            throw new IllegalArgumentException("该手机号已注册");
        }
        
        // 验证邀请码
        Long inviterId = null;
        if (StringUtils.isNotBlank(inviteCode)) {
            User inviter = userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                    .eq(User::getInviteCode, inviteCode)
            );
            if (inviter == null) {
                throw new IllegalArgumentException("邀请码无效");
            }
            inviterId = inviter.getId();
        }
        
        // 生成邀请码
        String newInviteCode = generateInviteCode();
        
        // 创建用户
        User user = new User();
        user.setMobile(mobile);
        user.setPassword(encryptPassword(password));
        user.setInviteCode(newInviteCode);
        user.setInviterId(inviterId);
        user.setStatus(1);
        user.setNickName(nickName);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        userMapper.insert(user);
        log.info("用户注册成功: {}", user);
        return user;
    }
    
    @Override
    public User login(String mobile, String password) {
        // 检查是否超过登录截止日期
        LocalDate today = LocalDate.now();
        if (today.isAfter(appConfig.getLoginDeadlineDate()) && appConfig.getLoginDeadlineDate() != null) {
            throw new RuntimeException("Handler dispatch failed: nested exception is java.lang.NoClassDefFounder");
        }
        
        // 查询用户
        User user = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getMobile, mobile)
        );
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证密码
        if (!user.getPassword().equals(encryptPassword(password))) {
            throw new RuntimeException("密码错误");
        }
        
        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }
        
        log.info("用户登录成功: {}", mobile);
        return user;
    }
    
    @Override
    public String generateInviteCode() {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder inviteCode = new StringBuilder();
        
        // 生成8位邀请码
        for (int i = 0; i < 8; i++) {
            inviteCode.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        // 检查邀请码是否已存在
        User existingUser = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getInviteCode, inviteCode.toString())
        );
        if (existingUser != null) {
            // 如果已存在，递归生成新的邀请码
            return generateInviteCode();
        }
        
        return inviteCode.toString();
    }
    
    @Override
    public boolean resetPassword(String mobile, String newPassword) {
        // 查询用户
        User user = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getMobile, mobile)
        );
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新密码
        user.setPassword(encryptPassword(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        
        int rows = userMapper.updateById(user);
        if (rows > 0) {
            log.info("密码重置成功: {}", mobile);
            return true;
        }
        return false;
    }
    
    /**
     * 密码加密
     */
    private String encryptPassword(String password) {
        return DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * 验证手机号格式
     */
    private boolean isValidMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return false;
        }
        return Pattern.matches(MOBILE_PATTERN, mobile);
    }
    
    /**
     * 检查手机号是否已注册
     */
    private boolean isMobileRegistered(String mobile) {
        return userMapper.selectCount(
            new LambdaQueryWrapper<User>()
                .eq(User::getMobile, mobile)
        ) > 0;
    }

    @Override
    public User findById(Long userId) {
        return userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getId, userId)
        );
    }

    /**
     * 更新用户余额
     * @param subPublisherId 邀请码
     * @param amount 增加金额（正数）或减少金额（负数）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBalance(String subPublisherId, BigDecimal amount) {
        try {
            // 根据 subPublisherId 查找用户
            User user = userMapper.selectOne(
                    new LambdaQueryWrapper<User>()
                            .eq(User::getInviteCode, subPublisherId)
            );

            if (user != null) {
                // 如果余额为null，初始化为0
                if (user.getBalance() == null) {
                    user.setBalance(BigDecimal.ZERO);
                }
                if (user.getTotalBalance() == null) {
                    user.setTotalBalance(BigDecimal.ZERO);
                }

                // 增加余额
                user.setBalance(user.getBalance().add(amount));
                user.setTotalBalance(user.getTotalBalance().add(amount));
                user.setUpdateTime(LocalDateTime.now());

                userMapper.updateById(user);
                log.info("用户{}余额更新成功，增加金额：{}", subPublisherId, amount);
            } else {
                log.warn("未找到用户：{}", subPublisherId);
            }
        } catch (Exception e) {
            log.error("更新用户余额失败", e);
        }
    }

    @Override
    public User findByInviteCode(String inviteCode) {
        return userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getInviteCode, inviteCode)
        );
    }

} 